import struct
import math
import amrtables
import array

def getbit(data, i):
    return (ord(data[i/8]) & (2**(i % 8))) >> (i % 8)

def reorderbits(data, mode):
    temp = [0] * len(data)
    t = amrtables.tables[mode]    
    for i in xrange(len(t)):
        temp[i/8] = (temp[i/8]) | getbit(data, t[i]) << (i % 8)
    r = ''
    for i in temp:
        r += chr(i)
    return r
    

def amrread(fn):
    f = open(fn, 'rb')
    data = f.read()
    f.close()
    header = '\x23\x21\x41\x4d\x52\x0a'
    if data[:6] == header:
        print "AMR header OK"
    else:
        print "Incorrect AMR header", data[:6]
    pos = 6
    codes = {0:13,1:14,2:16,3:18,4:20,5:21,6:27,7:32}
    count = 1
    frames = []
    while pos < len(data):
        c = ((struct.unpack('>H', '\x00' + data[pos])[0]) >> 3) & 7
        #print "Pos = ", pos, " frame count = ", count, " Code = ", c
        count = count + 1
        f = data[pos+1:pos+codes[c]]        
        tpl = (count, pos, c, reorderbits(f, c))
        #tpl = (count, pos, c, f)
        frames.append(tpl)
        pos = pos + codes[c]
    print "Total time = ", len(frames) * 0.020, " sec."
    return frames
        

def dot(v1, v2):
    r = 0
    for i in xrange(len(v1)):
        r += (ord(v1[i]) * ord(v2[i]))
    return r

def absv(v):
    return math.sqrt(dot(v,v))

def subv(v1, v2, q = 1):
    r = []
    vn1 = array.array('B', v1)
    vn2 = array.array('B', v2)
    for i in xrange(len(vn1)):
        r.append(vn1[i]/q - vn2[i]/q)
        #r.append((v1[i])/q - (v2[i])/q)
    return r

def addv(v1, v2, q = 1):
    r = []
    for i in xrange(len(v1)):
        r.append(ord(v1[i])/q + ord(v2[i])/q)
    return r

def theta(v1, v2):
    return math.acos(dot(v1, v2) / (absv(v1) * absv(v2)))
        
def amrcomp(fn1, fn2):
    f1 = amrread(fn1)
    f2 = amrread(fn2)
    # compare length
    t1 = len(f1) * 0.02
    t2 = len(f2) * 0.02
    if t1 == t2:
        print "Time equals = ", t1
    else:
        print "Diff: T1 = ", t1, " T2 = ", t2
        return 0
    for i in xrange(len(f1)):
        #print i, ": theta ", 180 * theta(f1[i][3], f2[i][3]) / math.pi
        #print i, ": |f1| = ", absv(f1[i][3]), " |f2| = ", absv(f2[i][3]), " diff = ", abs(absv(f1[i][3]) - absv(f2[i][3]))
        #print i, ": sub = ", subv(addv(f1[i][3],f1[i+1][3]), addv(f2[i][3],f2[i+1][3]), 1)
        print i, ": sub = ", subv(f1[i][3], f2[i][3], 1)
    
